/**
 * Copyright 2016 JustWayward Team
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.taptech.doufu.ui.view.readview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import com.taptech.doufu.ui.view.readview.util.ScreenUtils;
import com.taptech.doufu.ui.view.theme.read.ReadTheme;
import com.taptech.doufu.util.MobileState;
import com.taptech.doufu.util.UIUtil;


public abstract class BaseReadView extends View {

    protected int mScreenWidth;
    protected int mScreenHeight;

    protected PointF mTouch = new PointF();
    protected float actiondownX, actiondownY;
    protected float touch_down = 0; // 当前触摸点与按下时的点的差值

    protected Bitmap mCurPageBitmap, mNextPageBitmap;
    protected Canvas mCurrentPageCanvas, mNextPageCanvas;
    protected PageFactory pagefactory = null;

    protected OnReadStateChangeListener listener;
    protected String bookId;
    public boolean isPrepared = false;
    private Context context;
    Scroller mScroller;

    public void setChaptersList(SparseArray<String> array) {
        if (pagefactory != null) {
            pagefactory.setChaptersList(array);
        }
    }

    public BaseReadView(Context context, String bookId,  MobileState mobileState,int fontSize,float lineSpace, SparseArray<String> chaptersList,
                        OnReadStateChangeListener listener) {
        super(context);
        this.context = context;
        this.listener = listener;
        this.bookId = bookId;
        mScreenWidth = ScreenUtils.getScreenWidth();
        mScreenHeight = ScreenUtils.getScreenHeight();

        mCurPageBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.ARGB_8888);
        mNextPageBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.ARGB_8888);
        mCurrentPageCanvas = new Canvas(mCurPageBitmap);
        mNextPageCanvas = new Canvas(mNextPageBitmap);

        mScroller = new Scroller(getContext());

        pagefactory = new PageFactory(getContext(), bookId, mobileState,fontSize,lineSpace,chaptersList);
        pagefactory.setOnReadStateChangeListener(listener);
    }


    private int dx, dy;
    private long et = 0;
    private boolean cancel = false;
    private boolean center = false;
    private boolean rightButtom = false;

    public void setShowPocket(boolean showPocket) {
        isShowPocket = showPocket;
    }

    private boolean isShowPocket = false;

    /**
     * 设置自动阅读
     * @param isAutoPlay
     */
    public void setAutoPlay(boolean isAutoPlay) {
        this.isAutoPlay = isAutoPlay;
        if (isAutoPlay) {
            pagefactory.onDraw(mCurrentPageCanvas);
            listener.onFlip();
            noAnimation();
            postInvalidate();
            if (isAutoPlayLine) {
                pagefactory.setPrePicture();
                BookStatus status = pagefactory.nextPage();
                if (status == BookStatus.NO_NEXT_PAGE) {
                    listener.onTheEnd();
                } else if (status == BookStatus.LOAD_SUCCESS) {
                    pagefactory.setPicture();
                } else {
                }
            }
            starPlay();
        }else{
            height = 0;
            width = 0;
            pagefactory.onDrawProgress(mNextPageCanvas,0);
            if (isAutoPlayLine) {
                pagefactory.onDrawPre(mNextPageCanvas);
                postInvalidate();
                pagefactory.prePage();
            }else{
                pagefactory.onDraw(mNextPageCanvas);
            }

        }
    }

    public void setAutoPlayProgress(int changeHeight) {
        int nHeight = changeHeight+height;
        if(nHeight<0)
            nHeight = 0;
        if (nHeight > ScreenUtils.getScreenHeight()) {
            nHeight = ScreenUtils.getScreenHeight();
        }
        height = nHeight;
        if (changeHeight < 0) {
            pagefactory.onDrawPre(mNextPageCanvas);
        }
        pagefactory.onDrawPlay(mNextPageCanvas,nHeight);
        postInvalidate();
    }

    private boolean isAutoPlay = false;
    private boolean isWait = false;
    private static int FRUSH_VIEW_LINE = 1;
    private static int FRUSH_VIEW_PAGE = 2;
    Handler handler = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            if (msg.what == FRUSH_VIEW_LINE) {
                if (!isAutoPlayLine) {
                    return;
                }
                if (height < ScreenUtils.getScreenHeight()) {
                    pagefactory.onDrawPlay(mNextPageCanvas,height);
                    postInvalidate();
                }else{
                    height = 0;
                    pagefactory.setPrePicture();
                    BookStatus status = pagefactory.nextPage();
                    if (status == BookStatus.NO_NEXT_PAGE) {
                        listener.onTheEnd();
                    } else if (status == BookStatus.LOAD_SUCCESS) {
                        pagefactory.setPicture();
                    } else {
                    }
                    pagefactory.onDrawPlay(mNextPageCanvas,height);
                    postInvalidate();
                }
            } else if (msg.what == FRUSH_VIEW_PAGE) {
                if (width < ScreenUtils.getScreenWidth()) {
                    pagefactory.onDrawProgress(mNextPageCanvas,width);
                    postInvalidate();
                }else{
                    width = 0;
                    pagefactory.setPrePicture();
                    pageDown();
                }
            }
        }
    };

    public void updateSpeed(int allTime) {
        this.allTime = allTime;
        if (allTime / ScreenUtils.getScreenHeight() > 24) {
            this.increaseTime = 1;
            this.sleepTime = allTime/ScreenUtils.getScreenHeight();
        }else if(allTime/ScreenUtils.getScreenHeight()>12){
            this.increaseTime = 2;
            this.sleepTime = allTime/ScreenUtils.getScreenHeight()*2;
        }else{
            this.increaseTime = 3;
            this.sleepTime = allTime/ScreenUtils.getScreenHeight()*3;
        }
        if (this.sleepTime < 24) {
            this.sleepTime = 24;
            this.increaseTime = 4;
        }
    }

    public void setPlayType(boolean isAutoPlayLine) {
        this.isAutoPlayLine = isAutoPlayLine;
    }
    /**
     * 切换自动阅读类型
     * @param isAutoPlayLine
     */
    public void changePlayType(boolean isAutoPlayLine) {
        this.isAutoPlayLine = isAutoPlayLine;
        if(isAutoPlayLine){
            height = 0;
            updateSpeed(allTime);
            pagefactory.setPrePicture();
            BookStatus status = pagefactory.nextPage();
            if (status == BookStatus.LOAD_SUCCESS) {
                pagefactory.setPicture();
            }
        }else{
            pagefactory.onDrawPre(mNextPageCanvas);
            postInvalidate();
            pagefactory.prePage();
            width = 0;
            increaseTime = 1;
            sleepTime = allTime/ScreenUtils.getScreenWidth();
        }
    }

    private int height = 0;
    private int width = 0;
    private Thread thread;
    private int allTime = 20*1000;
    private int increaseTime = 1;
    private int sleepTime = 24;
    private boolean isAutoPlayLine = true;//是否是逐行扫描
    private void starPlay() {
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (isAutoPlay){
                        if (isAutoPlayLine) {
                            if (!isWait) {
                                Thread.sleep(sleepTime);
                                height+=increaseTime;
                                Message message = new Message();
                                message.what = FRUSH_VIEW_LINE;
                                handler.sendMessage(message);
                            }
                        }else{
                            Thread.sleep(sleepTime);
                            width+=increaseTime;
                            Message message = new Message();
                            message.what = FRUSH_VIEW_PAGE;
                            handler.sendMessage(message);
                        }

                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
    public void  waitPlay() {
        isWait = true;
    }

    public synchronized void restartPlay() {
        isWait = false;
    }

    public void pageUp() {
        pagefactory.onDraw(mCurrentPageCanvas);
        mTouch.x = 10;
        mTouch.y = 10;
        actiondownX = 10;
        actiondownY = 10;
        touch_down = 0;
        BookStatus status = pagefactory.prePage();
        if (status == BookStatus.NO_PRE_PAGE) {

        } else if (status == BookStatus.LOAD_SUCCESS) {
            abortAnimation();
            pagefactory.onDraw(mNextPageCanvas);
        } else {

        }
        listener.onFlip();
        startAnimation();
        postInvalidate();
    }

    public void pageDown() {
        pagefactory.onDraw(mCurrentPageCanvas);
        mTouch.x = ScreenUtils.getScreenWidth() - 10;
        mTouch.y = 10;
        actiondownX = ScreenUtils.getScreenWidth() - 10;
        actiondownY = 10;
        touch_down = 0;
        BookStatus status = pagefactory.nextPage();
        if (status == BookStatus.NO_NEXT_PAGE) {
            listener.onTheEnd();
        } else if (status == BookStatus.LOAD_SUCCESS) {
            abortAnimation();
            pagefactory.onDraw(mNextPageCanvas);
        } else {
        }
        listener.onFlip();
        startAnimation();
        postInvalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                et = System.currentTimeMillis();
                dx = (int) e.getX();
                dy = (int) e.getY();
                mTouch.x = dx;
                mTouch.y = dy;
                actiondownX = dx;
                actiondownY = dy;
                touch_down = 0;
                pagefactory.onDraw(mCurrentPageCanvas);
                if (actiondownX >= mScreenWidth / 3 && actiondownX <= mScreenWidth * 2 / 3
                        && actiondownY >= mScreenHeight / 3 && actiondownY <= mScreenHeight * 2 / 3) {
                    //显示或隐藏导航栏
                    center = true;
                    rightButtom = false;
                }else if(isShowPocket && actiondownX>=mScreenWidth*3/4 && actiondownY>= mScreenHeight*3/4){
                    rightButtom = true;
                    center = false;
                } else {
                    rightButtom = false;
                    center = false;
                    calcCornerXY(actiondownX, actiondownY);
                    if (actiondownX < mScreenWidth / 2) {// 从左翻
                        BookStatus status = pagefactory.prePage();
                        if (status == BookStatus.NO_PRE_PAGE) {
//                            UIUtil.toastMessage(context,"没有上一章啦");
                            return false;
                        } else if (status == BookStatus.LOAD_SUCCESS) {
                            abortAnimation();
                            pagefactory.onDraw(mNextPageCanvas);
                        } else {
                            return false;
                        }
                    } else if (actiondownX >= mScreenWidth / 2) {// 从右翻
                        BookStatus status = pagefactory.nextPage();
                        if (status == BookStatus.NO_NEXT_PAGE) {
//                            UIUtil.toastMessage(context,"没有下一章啦");
                            listener.onTheEnd();
                            return false;
                        } else if (status == BookStatus.LOAD_SUCCESS) {
                            abortAnimation();
                            pagefactory.onDraw(mNextPageCanvas);
                        } else {
                            return false;
                        }
                    }
                    listener.onFlip();
                    setBitmaps(mCurPageBitmap, mNextPageBitmap);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (center)
                    break;
                int mx = (int) e.getX();
                int my = (int) e.getY();
                cancel = (actiondownX < mScreenWidth / 2 && mx < mTouch.x) || (actiondownX > mScreenWidth / 2 && mx > mTouch.x);
                mTouch.x = mx;
                mTouch.y = my;
                touch_down = mTouch.x - actiondownX;
                this.postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:

                long t = System.currentTimeMillis();
                int ux = (int) e.getX();
                int uy = (int) e.getY();

                if (center) { // ACTION_DOWN的位置在中间，则不响应滑动事件
                    resetTouchPoint();
                    if (Math.abs(ux - actiondownX) < 5 && Math.abs(uy - actiondownY) < 5) {
                        listener.onCenterClick();
                        return false;
                    }
                    break;
                }

                if (rightButtom) {
                    resetTouchPoint();
                    if (Math.abs(ux - actiondownX) < 5 && Math.abs(uy - actiondownY) < 5) {
//                        listener.onCenterClick();
                        return false;
                    }
                    break;
                }

                if ((Math.abs(ux - dx) < 10) && (Math.abs(uy - dy) < 10)) {
                    if ((t - et < 1000)) { // 单击
                        startAnimation();
                    } else { // 长按
                        pagefactory.cancelPage();
                        restoreAnimation();
                    }
                    postInvalidate();
                    return true;
                }
                if (cancel) {
                    pagefactory.cancelPage();
                    restoreAnimation();
                    postInvalidate();
                } else {
                    startAnimation();
                    postInvalidate();
                }
                cancel = false;
                center = false;
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        calcPoints();
        drawCurrentPageArea(canvas);
        drawNextPageAreaAndShadow(canvas);
        drawCurrentPageShadow(canvas);
        drawCurrentBackArea(canvas);
    }

    protected abstract void drawNextPageAreaAndShadow(Canvas canvas);

    protected abstract void drawCurrentPageShadow(Canvas canvas);

    protected abstract void drawCurrentBackArea(Canvas canvas);

    protected abstract void drawCurrentPageArea(Canvas canvas);

    protected abstract void calcPoints();

    protected abstract void calcCornerXY(float x, float y);

    /**
     * 开启翻页
     */
    protected abstract void startAnimation();

    protected abstract void noAnimation();

    /**
     * 停止翻页动画（滑到一半调用停止的话  翻页效果会卡住 可调用#{restoreAnimation} 还原效果）
     */
    protected abstract void abortAnimation();

    /**
     * 还原翻页
     */
    protected abstract void restoreAnimation();

    protected abstract void setBitmaps(Bitmap mCurPageBitmap, Bitmap mNextPageBitmap);

    public abstract void setTheme(int theme);

    /**
     * 复位触摸点位
     */
    protected void resetTouchPoint() {
        mTouch.x = 0.1f;
        mTouch.y = 0.1f;
        touch_down = 0;
        calcCornerXY(mTouch.x, mTouch.y);
    }


    public void jumpToChapter(int chapter,int beginPos,int page) {
        resetTouchPoint();
        pagefactory.setCurrentPage(page);
        pagefactory.openBook(chapter, new int[]{beginPos, 0},true);
        pagefactory.onDraw(mCurrentPageCanvas);
        pagefactory.onDraw(mNextPageCanvas);
        postInvalidate();
    }

    public void jumpToChapter(int chapter) {
        resetTouchPoint();
        pagefactory.setCurrentPage(1);
        pagefactory.openBook(chapter, new int[]{0, 0},true);
        pagefactory.onDraw(mCurrentPageCanvas);
        pagefactory.onDraw(mNextPageCanvas);
        postInvalidate();
    }

    public void jumpToChapter(int chapter,int[] pos) {
        resetTouchPoint();
        pagefactory.openBook(chapter, pos,true);
        pagefactory.onDraw(mCurrentPageCanvas);
        pagefactory.onDraw(mNextPageCanvas);
        postInvalidate();
    }

    public void nextPage() {
        BookStatus status = pagefactory.nextPage();
        if (status == BookStatus.NO_NEXT_PAGE) {
            UIUtil.toastMessage(context,"没有下一页啦");
            return;
        } else if (status == BookStatus.LOAD_SUCCESS) {
            if (isPrepared) {
                pagefactory.onDraw(mCurrentPageCanvas);
                pagefactory.onDraw(mNextPageCanvas);
                postInvalidate();
            }
        } else {
            return;
        }

    }

    public void prePage() {
        BookStatus status = pagefactory.prePage();
        if (status == BookStatus.NO_PRE_PAGE) {
            UIUtil.toastMessage(context,"没有下一页啦");
            return;
        } else if (status == BookStatus.LOAD_SUCCESS) {
            if (isPrepared) {
                pagefactory.onDraw(mCurrentPageCanvas);
                pagefactory.onDraw(mNextPageCanvas);
                postInvalidate();
            }
        } else {
            return;
        }
    }





    public void setPosition(int[] pos) {
        int ret = pagefactory.openBook(pos[0], new int[]{pos[1], pos[2]},true);
        if (ret == 0) {
            listener.onLoadChapterFailure(pos[0]);
            return;
        }
        pagefactory.onDraw(mCurrentPageCanvas);
        postInvalidate();
    }

    public void removePageCache(int capter) {
        if (pagefactory != null) {
            pagefactory.removePageCache(capter);
        }
    }

    public int[] getReadPos() {
        return pagefactory.getPosition();
    }

    public String getHeadLine() {
        return pagefactory.getHeadLineStr().replaceAll("@", "");
    }

    public void setFontSize(int fontSize) {
        if (pagefactory != null) {
            pagefactory.setFontSize(fontSize);
            pagefactory.clearPageAllCache();
            jumpToChapter(pagefactory.getCurrentChapter());
        }
    }

    public void setLineSpace(float space) {
        if (pagefactory != null) {
            pagefactory.setLineSpace(space);
            pagefactory.clearPageAllCache();
            jumpToChapter(pagefactory.getCurrentChapter());
        }
    }

    public void clearPageAllCache() {
        if (pagefactory != null) {
            pagefactory.clearPageAllCache();
        }
    }

    public void setReadTheme(ReadTheme readTheme) {
        if (pagefactory != null) {
            pagefactory.setReadTheme(readTheme);
            jumpToChapter(pagefactory.getCurrentChapter(),new int[]{pagefactory.getCurBeginPos(),pagefactory.getCurEndPos()});
        }
    }

    public synchronized void setTitleText(String title) {
        if (pagefactory != null) {
            pagefactory.setTitleText(title);
        }
    }

    public void updateMobileState(MobileState mobileState) {
        if (pagefactory != null) {
            pagefactory.upDateMobileState(mobileState);
            postInvalidate();
        }
    }
}
